//
// Created by gastonfeng on 2022/8/22.
//
#include <rte_data.h>
#include"Rtos.h"
#include "nStream.h"
#include "plc_rte.h"

int nStream::tx_max_size() {
    return 0;
}


#ifndef THIS_IS_BOOTLOADER

void nStream::forward(uint8_t c) {
    if ((flag & FLAG_FORWARD) && forwardStream) {
        forwardStream->write(c);
    }
    tick_forward = Rtos::ticks() + rte_config.forward_timeout;
}

void nStream::closeForward() {
    forwardStream = nullptr;
    flag &= ~FLAG_FORWARD;
}

#endif

void nStream::begin(uint8_t address, bool generalCall) {
    logger.error("nStream::begin() not implemented");
}

u8 nStream::endTransmission(u8 sendStop) {
    logger.error("nStream::endTransmission() not implemented");
    return 0;
}

u8 nStream::endTransmission() {
    return endTransmission((u8) true);
}

int nStream::availableForWrite() {
    return 0;
}

int nStream::printNumber(unsigned long n, uint8_t base) {
    char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
    char *str = &buf[sizeof(buf) - 1];

    *str = '\0';

    // prevent crash if called with base == 1
    if (base < 2) {
        base = 10;
    }

    do {
        unsigned long m = n;
        n /= base;
        char c = m - base * n;
        *--str = c < 10 ? c + '0' : c + 'A' - 10;
    } while (n);

    return write(str);
}

//
// Created by gastonfeng on 2023/4/21.
//


int nStream::write(const uint8_t *buffer, int size) {
    int n = 0;
    while (size--) {
        if (write(*buffer++)) {
            n++;
        } else {
            break;
        }
    }
    return n;
}

int nStream::print(const char str[]) {
    return write(str);
}

int nStream::print(char c) {
    return write(c);
}

int nStream::print(unsigned char b, int base) {
    return print((unsigned long) b, base);
}

int nStream::print(int n, int base) {
    return print((long) n, base);
}

int nStream::print(unsigned int n, int base) {
    return print((unsigned long) n, base);
}

int nStream::print(long n, int base) {
    if (base == 0) {
        return write(n);
    } else if (base == 10) {
        if (n < 0) {
            int t = print('-');
            n = -n;
            return printNumber(n, 10) + t;
        }
        return printNumber(n, 10);
    } else {
        return printNumber(n, base);
    }
}

int nStream::print(unsigned long n, int base) {
    if (base == 0) {
        return write(n);
    } else {
        return printNumber(n, base);
    }
}

int nStream::print(long long n, int base) {
    if (base == 0) {
        return write(n);
    } else if (base == 10) {
        if (n < 0) {
            int t = print('-');
            n = -n;
            return printULLNumber(n, 10) + t;
        }
        return printULLNumber(n, 10);
    } else {
        return printULLNumber(n, base);
    }
}

int nStream::print(unsigned long long n, int base) {
    if (base == 0) {
        return write(n);
    } else {
        return printULLNumber(n, base);
    }
}

int nStream::print(double n, int digits) {
    return printFloat(n, digits);
}


int nStream::println(const char c[]) {
    int n = print(c);
    n += println();
    return n;
}

int nStream::println(char c) {
    int n = print(c);
    n += println();
    return n;
}

int nStream::println(unsigned char b, int base) {
    int n = print(b, base);
    n += println();
    return n;
}

int nStream::println(int num, int base) {
    int n = print(num, base);
    n += println();
    return n;
}

int nStream::println(unsigned int num, int base) {
    int n = print(num, base);
    n += println();
    return n;
}

int nStream::println(long num, int base) {
    int n = print(num, base);
    n += println();
    return n;
}

int nStream::println(unsigned long num, int base) {
    int n = print(num, base);
    n += println();
    return n;
}

int nStream::println(long long num, int base) {
    int n = print(num, base);
    n += println();
    return n;
}

int nStream::println(unsigned long long num, int base) {
    int n = print(num, base);
    n += println();
    return n;
}

int nStream::println(double num, int digits) {
    int n = print(num, digits);
    n += println();
    return n;
}


void nStream::flush() {
}

int nStream::println() {
    return write("\r\n");
}

int nStream::printFloat(double, uint8_t) {
    return 0;
}

int nStream::printULLNumber(unsigned long long int, uint8_t) {
    return 0;
}

int nStream::available() {
    return 0;
}

int nStream::read() {
    return 0;
}

int nStream::peek() {
    return 0;
}

#ifdef ARDUINO

int nStream::print(const __FlashStringHelper *ifsh) {
    return print(reinterpret_cast<const char *>(ifsh));
}

int nStream::print(const String &s) {
    return write((const uint8_t *)s.c_str(), s.length());
}

int nStream::println(const Printable &x) {
    int n = print(x);
    n += println();
    return n;
}

int nStream::println(const __FlashStringHelper *ifsh) {
    int n = print(ifsh);
    n += println();
    return n;
}


int nStream::println(const String &s) {
    int n = print(s);
    n += println();
    return n;
}

#endif
